home *** CD-ROM | disk | FTP | other *** search
- /* -------------------------------------------------------------------- */
- /* Mouse++ Version 3.0 mouse.cpp Revised 02/21/92 */
- /* */
- /* General mouse class for Turbo C++/Borland C++. */
- /* Copyright 1991, 1992 by Carl W. Moreland */
- /* This source code may be freely distributed as long as the copyright */
- /* notice remains intact. */
- /* -------------------------------------------------------------------- */
-
- #include <dos.h>
- #include "mouse.h"
-
- union REGS reg;
- struct SREGS sreg;
-
- Mouse mouse;
- struct time t;
-
- unsigned char Mouse::exists = 0;
- unsigned char Mouse::enabled = 0;
- unsigned char Mouse::visible = 0;
- unsigned char Mouse::buttons = 0;
- unsigned char Mouse::button = 0;
- int Mouse::x = 0;
- int Mouse::y = 0;
- int Mouse::xcount = 0;
- int Mouse::ycount = 0;
- unsigned char Mouse::hotx = 0;
- unsigned char Mouse::hoty = 0;
- int Mouse::oldeventmask = 0;
- int Mouse::oldeventseg = 0;
- int Mouse::oldeventoff = 0;
- unsigned Mouse::clickThreshold = 250;
- unsigned char Mouse::handlerInstalled = 0;
- unsigned char Mouse::HeadPtr = 0;
- unsigned char Mouse::TailPtr = 0;
- unsigned char Mouse::event = 0x00;
-
- /* -------------------------------------------------------------------- */
-
- Mouse::Mouse(void) // reset mouse - constructor
- {
- int found;
-
- _AX = 0x00;
- geninterrupt(0x33);
- found = _AX;
- buttons = _BX;
- visible = 0;
-
- if(found)
- exists = 1;
- if(!exists) return;
-
- _ES = 0;
- _DX = 0;
- _CX = 0; // clear the event handler
- _AX = 0x14;
- geninterrupt(0x33);
- oldeventmask = _CX; // save the old event handler
- oldeventoff = _DX;
- oldeventseg = _ES;
-
- _AX = 0x24; // get the mouse info
- geninterrupt(0x33);
- Info.majorvers = _BH;
- Info.minorvers = _BL;
- Info.type = _CH;
- Info.irq = _CL;
- }
-
- Mouse::~Mouse(void) // restore mouse - destructor
- {
- if(!exists) return;
- _AX = 0x00; // reset mouse
- geninterrupt(0x33);
-
- if(oldeventmask) // restore old event handler
- {
- _ES = oldeventseg;
- _DX = oldeventoff;
- _CX = oldeventmask;
- _AX = 0x14;
- geninterrupt(0x33);
- }
- }
-
- void Mouse::Enable(void) // enable the mouse
- {
- if(!exists || enabled) return;
-
- if(eventMask && !handlerInstalled) // re-install event handler
- {
- InstallHandler(eventMask, eventHandler);
- handlerInstalled = 1;
- }
- enabled = 1;
- }
-
- void Mouse::Disable(void) // disable the mouse
- {
- if(!exists || !enabled) return;
-
- if(handlerInstalled)
- {
- ClearHandler(); // disable the event handler
- ClearClick(LEFTBUTTON);
- ClearClick(RIGHTBUTTON); // clear the multi-click buffers
- ClearClick(CENTERBUTTON);
- }
- Hide(); // turn the cursor off
- enabled = 0;
- }
-
- void Mouse::Show() // show mouse cursor
- {
- if(!exists || !enabled) return;
- _AX = 0x01;
- geninterrupt(0x33);
- if(visible < 1) visible++; // visible should now be 1
- }
-
- void Mouse::Hide(void) // hide mouse cursor
- {
- if(!exists || !enabled) return;
- if(visible < 1) return;
- _AX = 0x02;
- geninterrupt(0x33);
- visible--; // visible should now be 0
- }
-
- void Mouse::Move(int x, int y) // move cursor to col, row
- { // col & row are pixel coordinates
- if(!exists || !enabled) return;
- _DX = y;
- _CX = x;
- _AX = 0x04;
- geninterrupt(0x33);
- }
-
- void Mouse::xLimit(int min, int max) // set min/max column range
- { // min & max are pixel coordinates
- if(!exists) return;
- _DX = max;
- _CX = min;
- _AX = 0x07;
- geninterrupt(0x33);
- }
-
- void Mouse::yLimit(int min, int max) // set min/max row range
- { // min & max are pixel coordinates
- if(!exists) return;
- _DX = max;
- _CX = min;
- _AX = 0x08;
- geninterrupt(0x33);
- }
-
- void Mouse::MickToPix(int horiz, int vert)
- { // set the mickey to pixel ratio
- if(!exists) return;
- _DX = vert;
- _CX = horiz;
- _AX = 0x0F;
- geninterrupt(0x33);
- }
-
- void Mouse::SetSpeedThreshold(unsigned speed)
- { // set speed change threshold
- if(!exists) return;
- _DX = speed;
- _AX = 0x13;
- geninterrupt(0x33);
- }
-
- void Mouse::SetGraphicsCursor(GraphicsCursor& cursor)
- { // change the graphics cursor
- if(!exists) return;
- _ES = FP_SEG(cursor.image);
- _DX = FP_OFF(cursor.image);
- _CX = cursor.hoty;
- _BX = cursor.hotx;
- _AX = 0x09;
- geninterrupt(0x33);
- hotx = cursor.hotx;
- hoty = cursor.hoty;
- }
-
- void Mouse::SetTextCursor(TextCursor& cursor)
- { // change the text cursor
- if(!exists) return;
- _DX = cursor.arg2;
- _CX = cursor.arg1;
- _BX = cursor.type;
- _AX = 0x0A;
- geninterrupt(0x33);
- hotx = 0;
- hoty = 0;
- }
-
- void Mouse::Position(void) // update cursor position &
- { // button status
- if(!exists || !enabled) return;
- _AX = 0x03;
- geninterrupt(0x33);
- button = _BX;
- x = _CX;
- y = _DX;
- }
-
- int Mouse::Pressed(int mbutton) // check press status of button
- {
- if(!exists || !enabled) return(0);
-
- if(handlerInstalled)
- {
- if(mbutton == LEFTBUTTON)
- return(event & LB_PRESSED);
- else if(mbutton == RIGHTBUTTON)
- return(event & RB_PRESSED);
- else if(mbutton == CENTERBUTTON)
- return(event & CB_PRESSED);
- }
-
- _BX = mbutton;
- _AX = 0x05;
- geninterrupt(0x33);
- button = _AX;
- int BX = _BX;
- if(BX)
- {
- x = _CX;
- y = _DX;
- }
- return(BX);
- }
-
- int Mouse::Released(int mbutton) // check release status of button
- {
- if(!exists || !enabled) return(0);
-
- if(handlerInstalled)
- {
- if(mbutton == LEFTBUTTON)
- return(event & LB_RELEASED);
- else if(mbutton == RIGHTBUTTON)
- return(event & RB_RELEASED);
- else if(mbutton == CENTERBUTTON)
- return(event & CB_RELEASED);
- }
-
- _AX = 0x06;
- _BX = mbutton;
- geninterrupt(0x33);
- button = _AX;
- int BX = _BX;
- if(BX)
- {
- x = _CX;
- y = _DX;
- }
- return(BX);
- }
-
- void Mouse::Motion(void) // get # of mickeys moved
- {
- if(!exists || !enabled) return;
- _AX = 0x0B;
- geninterrupt(0x33);
- xcount = _CX;
- ycount = _DX;
- }
-
- int Mouse::InBox(int left, int top, int right, int bottom)
- { // see if mouse is in a box
- if(!exists || !enabled) return(0);
-
- if((x>=left) && (y>=top) && (x<=right) && (y<=bottom))
- return(1);
- return(0);
- }
-
- void Mouse::Exclude(int left, int top, int right, int bottom)
- { // set up exclusion area
- if(!exists || !enabled) return;
-
- if((x >= (left-15+hotx)) && (y >= (top-15+hoty)) &&
- (x <= (right+hotx)) && (y <= (bottom+hoty)))
- Hide();
- else
- Show();
- }
-
- void Mouse::SetClickThreshold(unsigned time)
- {
- clickThreshold = time; // time is in milliseconds
- }
-
- int Mouse::MultiClick(int mbutton) // check for multiple clicks
- {
- if(!exists || !enabled) return(0);
-
- return Click[mbutton].count;
- }
-
- int Mouse::DoubleClick(int mbutton) // check for double clicks
- {
- if(!exists || !enabled) return(0);
-
- return (Click[mbutton].count == 2);
- }
-
- void Mouse::ClearClick(int mbutton) // clear the MultiClick buffer
- {
- if(!exists || !enabled) return;
-
- Click[mbutton].count = 0;
- }
-
- /* ----- Event Driver routines ---------------------------------------- */
-
- void Mouse::InstallHandler(unsigned mask, void interrupt (*handler)(void))
- {
- if(!exists) return; // set up an event handler
-
- _ES = FP_SEG(handler);
- _DX = FP_OFF(handler);
- _CX = mask;
- _AX = 0x14;
- geninterrupt(0x33);
-
- handlerInstalled = 1;
- HeadPtr = 0;
- TailPtr = 0;
- eventMask = mask;
- eventHandler = handler;
- }
-
- void Mouse::ClearHandler(void) // clear the event handler
- {
- if(!exists) return;
-
- _ES = 0;
- _DX = 0;
- _CX = 0;
- _AX = 0x14;
- geninterrupt(0x33);
-
- handlerInstalled = 0;
- HeadPtr = 0;
- TailPtr = 0;
- }
-
- /* Mouse::Save - stuff the event info in the event buffer */
-
- void Mouse::Save(int event, int button, int x, int y, int xcount, int ycount)
- {
- unsigned char keymask;
- long time;
-
- if((HeadPtr == TailPtr-1) || // see if the buffer is full
- (HeadPtr == MOUSE_BUFFER_SIZE-1 && TailPtr == 0))
- return;
-
- if((event & LB_PRESSED) || (event & RB_PRESSED) || (event & CB_PRESSED))
- {
- gettime(&t); // get the event time
- time = (long)t.ti_hour*3600000L + // convert to milliseconds
- (long)t.ti_min*60000L +
- (long)t.ti_sec*1000L +
- (long)t.ti_hund*10L;
-
- _AH = 0x02;
- geninterrupt(0x16); // get the keyshift mask
- keymask = _AL;
-
- button += keymask << 4; // add it to the button mask
- if(keymask & 0x03)
- button += 0x08;
- }
- else
- time = 0; // no button press so time not needed
-
- Buffer[HeadPtr].event = event; // store the info in the event buffer
- Buffer[HeadPtr].button = button;
- Buffer[HeadPtr].x = x;
- Buffer[HeadPtr].y = y;
- Buffer[HeadPtr].xcount = xcount;
- Buffer[HeadPtr].ycount = ycount;
- Buffer[HeadPtr].time = time;
-
- if(++HeadPtr >= MOUSE_BUFFER_SIZE) // increment the head ptr
- HeadPtr = 0;
- }
-
- void interrupt MouseHandler(void) // default event handler
- {
- mouse.Save(_AX,_BX,_CX,_DX,_DI,_SI); // save the normal stuff
- EventExit(); // required for interrupt function
- }
-
- /* Mouse::GetEvent - read the event buffer and put info into the class */
-
- void Mouse::GetEvent(void)
- {
- if(!exists || !enabled) return;
-
- int mbutton;
-
- if(HeadPtr != TailPtr)
- {
- event = Buffer[TailPtr].event;
- button = Buffer[TailPtr].button;
- x = Buffer[TailPtr].x;
- y = Buffer[TailPtr].y;
- xcount = Buffer[TailPtr].xcount;
- ycount = Buffer[TailPtr].ycount;
-
- if(Buffer[TailPtr].time) // store info for MultiClick()
- {
- if(event & LB_PRESSED)
- mbutton = LEFTBUTTON;
- else if(event & RB_PRESSED)
- mbutton = RIGHTBUTTON;
- else if(event & CB_PRESSED)
- mbutton = CENTERBUTTON;
-
- if((Buffer[TailPtr].time - Click[mbutton].time) < clickThreshold)
- Click[mbutton].count++;
- else
- Click[mbutton].count = 1;
-
- Click[mbutton].time = Buffer[TailPtr].time;
- }
-
- if(++TailPtr >= MOUSE_BUFFER_SIZE)
- TailPtr = 0;
- }
- else
- {
- event = 0;
- xcount = 0;
- ycount = 0;
- }
- }
-
- void Mouse::ClearEvent(void) // clear the current event
- {
- event = 0;
- button = 0;
- x = 0;
- y = 0;
- xcount = 0;
- ycount = 0;
- }
-
- void Mouse::ClearBuffer(void) // clear the event buffer
- {
- HeadPtr = 0;
- TailPtr = 0;
- }
-